package com.cetc.sdp.mzga.service.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import com.cetc.sdp.mzga.service.server.StatServer;
import com.cetc.sdp.mzga.service.pojo.HbaseRangeScan;
import com.cetc.sdp.mzga.service.pojo.QueryResult;

public class Stat implements StatServer{
	
	private final static  String WIFI_BASIC_TBL      = "MZGA.DUMP_SDP_MZGA_BUSI_WIFI_BASIC";//the prefix of the wifi basic table ,like TEST.DUMP_SDP_MZGA_BUSI_WIFI_BASIC_201707
	
	private final static  String ROWKEY_NAME         = "ID";
	 
	private final static  String PHMAC_FLD_NAME      = "MAC";
	
	private final static  String END_TIME            = "END_TIME";
	
	private final static  String ROWKEY_SUFFIX       = "0000000000000";//12 byte mac +1 byte random num
	
	private final static  String ROWKEY_SUFFIX_ANALY = "0000000000000000000000";//21 byte device num +1 byte random num
	
	private final static  String ANALY_TBL_SUFFIX    = "ANALY";
	
	
	//get the distinct phone mac from the wifi basic table through device_num and time
	private List<String> getPhoneMac(String starttime,String endtime,String deivicenum,final String tblname) throws Exception{
		
		String rowKeyProfoxStart = deivicenum+starttime+ROWKEY_SUFFIX;
		String rowKeyProfoxEnd   = deivicenum+endtime+ROWKEY_SUFFIX;
		
		return  HbaseRangeScan.rangeDistinctScan(rowKeyProfoxStart,rowKeyProfoxEnd, ROWKEY_NAME,PHMAC_FLD_NAME,tblname);
	}
	
	@Override		
	public List<String> getPhoneMacByDeviceNum(String starttime,String endtime,String deivicenum) throws Exception{
		if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime) || StringUtils.isEmpty(deivicenum)) {
			 throw new RuntimeException("The input arguments is null !");
		}
		if(starttime.length() != 14 || endtime.length() != 14 || deivicenum.length() != 21) {
			 throw new RuntimeException("The input arguments is not regular !");
		}
		
		String startMoth = starttime.substring(0, 6);
		String endMoth   = endtime.substring(0, 6);		
		int startNum = Integer.valueOf(startMoth);
		int endNum = Integer.valueOf(endMoth);
		if((endNum-startNum) > 1 || (endNum-startNum) <0){
			 throw new RuntimeException("The time range is greater than 1 month or lesser than 0!");
		}
		
		//get the phone macs and remove duplicates
		List<String> phoneMacs = new ArrayList<String>();
		if(endNum == startNum){
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth; 
			phoneMacs = getPhoneMac(starttime,endtime,deivicenum,qtbl);
		}
		else{
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth;
			phoneMacs = getPhoneMac(starttime,String.valueOf(startNum+1)+"00000000",deivicenum,qtbl);
			qtbl = WIFI_BASIC_TBL+'_'+endMoth;
			List<String> endMacs = getPhoneMac(String.valueOf(endNum)+"00000000",endtime,deivicenum,qtbl);
			phoneMacs.removeAll(endMacs);
			phoneMacs.addAll(endMacs);
		}		

		return phoneMacs;
	}
	
	
	
	//count all rows from the wifi basic table through device_num and time
	private int countMac(String starttime,String endtime,String deivicenum,final String tblname) throws Exception{
		
		String rowKeyProfoxStart = deivicenum+starttime+ROWKEY_SUFFIX;
		String rowKeyProfoxEnd   = deivicenum+endtime+ROWKEY_SUFFIX;
		
		return  HbaseRangeScan.rangeCount(rowKeyProfoxStart,rowKeyProfoxEnd, ROWKEY_NAME, tblname);
	}
	
	@Override
	public int countRowsByDeviceNum(String starttime,String endtime,String deivicenum) throws Exception{
		if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime) || StringUtils.isEmpty(deivicenum)) {
			 throw new RuntimeException("The input arguments is null !");
		}
		if(starttime.length() != 14 || endtime.length() != 14 || deivicenum.length() != 21) {
			 throw new RuntimeException("The input arguments is not regular !");
		}
		
		String startMoth = starttime.substring(0, 6);
		String endMoth   = endtime.substring(0, 6);		
		int startNum = Integer.valueOf(startMoth);
		int endNum = Integer.valueOf(endMoth);
		if((endNum-startNum) > 1 || (endNum-startNum) <0){
			 throw new RuntimeException("The time range is greater than 1 month or lesser than 0!");
		}
		
		int num = 0;
		if(endNum == startNum){
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth; 		
			num = countMac(starttime,endtime,deivicenum,qtbl);
		}
		else{
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth;
			num = countMac(starttime,String.valueOf(startNum+1)+"00000000",deivicenum,qtbl);
			qtbl = WIFI_BASIC_TBL+'_'+endMoth;
			int endnum = countMac(String.valueOf(endNum)+"00000000",endtime,deivicenum,qtbl);
			num += endnum;
		}
		
		return num;
	}
	
	
	
	
	//get the query results (phone mac ,startTime,endTime) from the wifi basic table through device_num and time
	private List<QueryResult> getPMacandTime(String starttime,String endtime,String deivicenum,final String tblname) throws Exception{
		String rowKeyProfoxStart = deivicenum+starttime+ROWKEY_SUFFIX;
		String rowKeyProfoxEnd   = deivicenum+endtime+ROWKEY_SUFFIX;
		
		List<String> getfldnames =new ArrayList<String>(Arrays.asList(ROWKEY_NAME,PHMAC_FLD_NAME,END_TIME));
		List<Map<String,String>> data = HbaseRangeScan.rangeScan(rowKeyProfoxStart, rowKeyProfoxEnd, ROWKEY_NAME, getfldnames, tblname);
		
		//translate to QueryResult
		List<QueryResult> results = new ArrayList<QueryResult>();
		for(Map<String,String> r : data){
			int lth = r.get(ROWKEY_NAME).length();
			String num = r.get(PHMAC_FLD_NAME);
			String startTime;
			if( lth <= 36 ){
				startTime = r.get(ROWKEY_NAME).substring(21,lth-1);
			}
			else {
			    startTime = r.get(ROWKEY_NAME).substring(21, 35);
			}
		    String endTime   = r.get(END_TIME);
		    if(null != endTime){
		    		endTime = endTime.replace("-", "").replace(":", "").replace(" ", "");
		    }
		    
			results.add(new QueryResult(num,startTime,endTime));
		}
		return results;		
	}
	
	
	
	@Override
	public List<QueryResult> qureyRowsByDeviceNum(String starttime,String endtime,String deivicenum) throws Exception{
		if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime) || StringUtils.isEmpty(deivicenum)) {
			 throw new RuntimeException("The input arguments is null !");
		}
		if(starttime.length() != 14 || endtime.length() != 14 || deivicenum.length() != 21) {
			 throw new RuntimeException("The input arguments is not regular !");
		}
		
		String startMoth = starttime.substring(0, 6);
		String endMoth   = endtime.substring(0, 6);		
		int startNum = Integer.valueOf(startMoth);
		int endNum = Integer.valueOf(endMoth);
		if((endNum-startNum) > 1 || (endNum-startNum) <0){
			 throw new RuntimeException("The time range is greater than 1 month or lesser than 0!");
		}
				
		//get the all query results
		List<QueryResult> deviceNums = new ArrayList<QueryResult>();
		if(endNum == startNum){
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth; 		
			deviceNums = getPMacandTime(starttime,endtime,deivicenum,qtbl);
		}
		else{
			String qtbl = WIFI_BASIC_TBL+'_'+startMoth;
			deviceNums = getPMacandTime(starttime,String.valueOf(startNum+1)+"00000000",deivicenum,qtbl);
			qtbl = WIFI_BASIC_TBL+'_'+endMoth;
			deviceNums.addAll(getPMacandTime(String.valueOf(endNum)+"00000000",endtime,deivicenum,qtbl));
		}
	
		return deviceNums;
	}
	
	
	
	
	
	
	//get the query results  device num ,startTime,endTime  from the wifi basic analyse  table through phone mac and time
		private List<QueryResult> getDNumandTime(String starttime,String endtime,String phonemac,final String tblname) throws Exception{
			String phoneMac          = phonemac.replaceAll("-","");
			String rowKeyProfoxStart = phoneMac+starttime+ROWKEY_SUFFIX_ANALY;
			String rowKeyProfoxEnd   = phoneMac+endtime+ROWKEY_SUFFIX_ANALY;
			
			List<String> getfldnames =new ArrayList<String>(Arrays.asList(ROWKEY_NAME,END_TIME));
			
			List<Map<String,String>> data = HbaseRangeScan.rangeScan(rowKeyProfoxStart, rowKeyProfoxEnd, ROWKEY_NAME, getfldnames, tblname);
			
			//translate to QueryResult
			List<QueryResult> results = new ArrayList<QueryResult>();
			for(Map<String,String> r : data){
				int lth = r.get(ROWKEY_NAME).length();
				String num;
				String startTime;
				if( lth <= 27 ){
					num       = null;
					startTime = r.get(ROWKEY_NAME).substring(12,lth-1);
				}
				else {
					num       = r.get(ROWKEY_NAME).substring(26,lth-1);
				    startTime = r.get(ROWKEY_NAME).substring(12, 26);
				}
		
			    String endTime   = r.get(END_TIME);
			    if(null != endTime){
			    		endTime = endTime.replace("-", "").replace(":", "").replace(" ", "");
			    }
			    		
				results.add(new QueryResult(num,startTime,endTime));
			}
			return results;
		}
		
		@Override
		public List<QueryResult> getDNumTimeByPhoneMac(String starttime,String endtime,String phonemac) throws Exception{
			if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime) || StringUtils.isEmpty(phonemac)) {
				 throw new RuntimeException("The input arguments is null !");
			}
			if(starttime.length() != 14 || endtime.length() != 14 || phonemac.length() != 17) {
				 throw new RuntimeException("The input arguments is not regular !");
			}
			
			String startMoth = starttime.substring(0, 6);
			String endMoth   = endtime.substring(0, 6);		
			int startNum = Integer.valueOf(startMoth);
			int endNum = Integer.valueOf(endMoth);
			if((endNum-startNum) > 1 || (endNum-startNum) <0){
				 throw new RuntimeException("The time range is greater than 1 month or lesser than 0!");
			}
			
			String analyTablePrefix = WIFI_BASIC_TBL+'_'+ANALY_TBL_SUFFIX;
			//get the all query results
			List<QueryResult> deviceNums = new ArrayList<QueryResult>();
			if(endNum == startNum){
				String qtbl = analyTablePrefix+'_'+startMoth; 
				deviceNums = getDNumandTime(starttime,endtime,phonemac,qtbl);			
			}
			else{
				String qtbl = analyTablePrefix+'_'+startMoth;
				deviceNums = getDNumandTime(starttime,String.valueOf(startNum+1)+"00000000",phonemac,qtbl);
				qtbl = analyTablePrefix+'_'+endMoth;
				deviceNums.addAll(getDNumandTime(String.valueOf(endNum)+"00000000",endtime,phonemac,qtbl));			
			}	
			return deviceNums;
			
		}
		
	
	
	
	
	//count all rows from the wifi basic analyse  table through phone mac and time
	private int countDevNum(String starttime,String endtime,String phonemac,final String tblname) throws Exception{
		String phoneMac          = phonemac.replaceAll("-","");
		String rowKeyProfoxStart = phoneMac+starttime+ROWKEY_SUFFIX_ANALY;
		String rowKeyProfoxEnd   = phoneMac+endtime+ROWKEY_SUFFIX_ANALY;
		
		return  HbaseRangeScan.rangeCount(rowKeyProfoxStart,rowKeyProfoxEnd, ROWKEY_NAME, tblname);
	}
	
	
	@Override
	public int countRowsByPhoneMac(String starttime,String endtime,String phonemac) throws Exception{
		if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime) || StringUtils.isEmpty(phonemac)) {
			 throw new RuntimeException("The input arguments is null !");
		}
		if(starttime.length() != 14 || endtime.length() != 14 || phonemac.length() != 17) {
			 throw new RuntimeException("The input arguments is not regular !");
		}
		
		String startMoth = starttime.substring(0, 6);
		String endMoth   = endtime.substring(0, 6);		
		int startNum = Integer.valueOf(startMoth);
		int endNum = Integer.valueOf(endMoth);
		if((endNum-startNum) > 1 || (endNum-startNum) <0){
			 throw new RuntimeException("The time range is greater than 1 month or lesser than 0!");
		}
		
		String analyTablePrefix = WIFI_BASIC_TBL+'_'+ANALY_TBL_SUFFIX;
				
		int num = 0;
		if(endNum == startNum){
			String qtbl = analyTablePrefix+'_'+startMoth; 		
			num = countDevNum(starttime,endtime,phonemac,qtbl);
		}
		else{
			String qtbl = analyTablePrefix+'_'+startMoth;
			num = countDevNum(starttime,String.valueOf(startNum+1)+"00000000",phonemac,qtbl);
			qtbl = analyTablePrefix+'_'+endMoth;
			int endnum = countDevNum(String.valueOf(endNum)+"00000000",endtime,phonemac,qtbl);
			num += endnum;
		}
		
		return num;
	}
}
